﻿namespace IceCS.DataStructure.Core.Stack
{
    /// <summary>
    /// 链式栈
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class LinkedStack<T> : IStack<T>
    {
        /// <summary>
        /// 栈顶指示器
        /// </summary>
        public StackNode<T> Top { get; set; }

        /// <summary>
        /// 栈中结点数
        /// </summary>
        public int Count { get; private set; }

        /// <summary>
        /// 
        /// </summary>
        public bool IsEmpty => Top == null;

        /// <summary>
        /// 
        /// </summary>
        public LinkedStack()
        {
            Top = null;
            Count = 0;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T this[int index]
        {
            get
            {
                StackNode<T> node = Top;
                var restCount = Count - 1 - index;
                while (restCount > 0)
                {
                    node = Top.Next;
                    restCount--;
                }
                return node.Data;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        public void Push(T data)
        {
            var node = new StackNode<T>(data);
            if (IsEmpty)
            {
                Top = node;
            }
            else
            {
                node.Next = Top;
                Top = node;
            }
            Count++;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public T Pop()
        {
            if (IsEmpty)
            {
                return default;
            }
            StackNode<T> node = Top;
            Top = Top.Next;
            Count--;
            return node.Data;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public T GetTop()
        {
            if (IsEmpty)
            {
                return default;
            }
            return Top.Data;
        }

        /// <summary>
        /// 
        /// </summary>
        public void Clear()
        {
            Top = null;
            Count = 0;
        }
    }
}
